﻿#include "../../x/xctlDefine.h"
#include "../../ctlImage.h"
#include "../../x/draw/draw.h"

namespace swui
{
	void draw_image(ctlRect rect, _ctlInterior::drawInfo* info, std::shared_ptr<ctlImage> image,
		ctlImageRepeat repeat, unsigned char alpha, bool mask, ctlColor maskColor,
		_ctlInterior::tempAlphaDC& alphaDC)
	{
		Graphics * graphics = reinterpret_cast<Graphics*>(info->graphics);
		Rect src(0, 0, image->getWidth(), image->getHeight());
		Rect dest = src;
		dest.Offset(rect.x, rect.y);
		bool repX = !enumTypeAndIsNull(repeat, ctlImageRepeat::repeatX), 
			repY = !enumTypeAndIsNull(repeat, ctlImageRepeat::repeatY);
		if(!enumTypeAndIsNull(repeat, ctlImageRepeat::scaleX))
			dest.Width = rect.cx;
		if(!enumTypeAndIsNull(repeat, ctlImageRepeat::scaleY))
			dest.Height = rect.cy;
			
		Bitmap* bitmap = reinterpret_cast<Bitmap*>(image->getGdipHandle());
		HDC hDC = NULL;
		bool color24 = image->isColor24();
		if(color24) hDC = reinterpret_cast<HDC>(image->getDC());
		BLENDFUNCTION bf = {0};
		bf.BlendOp = AC_SRC_OVER;
		bf.SourceConstantAlpha = alpha;

		do {
			do {
				if(!color24 || image->isMatrixEnabled())
				{
					ImageAttributes attr;
					if(alpha != 255)
					{
						ColorMatrix matrix5 = { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 , 
							0, 0, 1, 0, 0, 0, 0, 0, alpha / 255.0f, 0, 0, 0, 0, 0, 1 };
						attr.SetColorMatrix(&matrix5);
					}
					if(mask)
					{
						ColorMap map;
						map.oldColor = MAKE_COLOR32(maskColor);
						map.newColor = Color(0, 0, 0, 0);
						attr.SetRemapTable(1, &map);
					}

					Matrix matrix;
					if(image->isMatrixEnabled())
					{
						graphics->GetTransform(&matrix);
						graphics->SetTransform(image->getNativeMatrix());
					}

					graphics->DrawImage(bitmap, dest, src.X, src.Y, 
						src.Width, src.Height, UnitPixel, alpha != 255 || mask ? &attr : nullptr);

					if(image->isMatrixEnabled())
						graphics->SetTransform(&matrix);
				} else if(alpha != 255) {
					if(mask)
					{
						alphaDC.require(dest.Width + 1, dest.Height + 1);
						//拷贝目标 DC 图像作为背景
						BitBlt(alphaDC.getDC(), 0, 0, dest.Width, dest.Height, info->hDC, dest.X, dest.Y, SRCCOPY);
						//绘制遮罩
						TransparentBlt(alphaDC.getDC(), 0, 0, dest.Width, dest.Height, hDC, 
							src.X, src.Y, src.Width, src.Height, MAKE_SYSTEM_RGB(maskColor & 0xffffff));
						//透明度混合
						AlphaBlend(info->hDC, dest.X, dest.Y, dest.Width, dest.Height, 
							alphaDC.getDC(), 0, 0, dest.Width, dest.Height, bf);
					} else AlphaBlend(info->hDC, dest.X, dest.Y, dest.Width, dest.Height, 
						hDC, src.X, src.Y, src.Width, src.Height, bf);
				} else if(mask) {
					TransparentBlt(info->hDC, dest.X, dest.Y, dest.Width, dest.Height, 
						hDC, src.X, src.Y, src.Width, src.Height, MAKE_SYSTEM_RGB(maskColor & 0xffffff));
				} else if(dest.Width != src.Width || dest.Height != src.Height) {
					StretchBlt(info->hDC, dest.X, dest.Y, dest.Width, dest.Height, 
						hDC, src.X, src.Y, src.Width, src.Height, SRCCOPY);
				} else { 
					BitBlt(info->hDC, dest.X, dest.Y, dest.Width, dest.Height, 
						hDC, src.X, src.Y, SRCCOPY);
				}
				dest.X += dest.Width;
			} while(dest.X < rect.cx + rect.x && repX);
			dest.Y += dest.Height;
		} while(dest.Y < rect.cy + rect.y && repY);
	}
}